package jmcnet.libcommun.security
{
	import jmcnet.libcommun.communs.exceptions.ExceptionTechnique;
	import jmcnet.libcommun.communs.newjmcnetds.BlazeDSService;
	import jmcnet.libcommun.logger.JMCNetLogger;
	
	import mx.messaging.Channel;
	import mx.messaging.ChannelSet;
	import mx.messaging.config.ServerConfig;
	import mx.rpc.AsyncResponder;
	import mx.rpc.AsyncToken;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.remoting.RemoteObject;
	
	[Bindable]
	public class SessionManagerBlazeDSImpl extends BaseSessionManager
	{
		private var _loginTemp:String;
		private var _serviceSecurity:BlazeDSService;
		private var _channelSet:ChannelSet;
		private var defaultRemoteObj:RemoteObject=null;
		
		/**
		 * Instancie un SessionManager pour BlazeDS.
		 * @param remoteObject : le remoteObject offrant un accès à des services coté serveur permettant l'acces aux infos de l'utilisateur connecte.
		 * 			Si non fourni, un remoteObject par defaut est utilisé.
		 */
		public function SessionManagerBlazeDSImpl(serviceSecurity:BlazeDSService) {
			// Si null on utilise la remoteObject par defaut
			if (serviceSecurity == null) {
				JMCNetLogger.debug("Pas de serviceSecurity. C'est une erreur");
				throw new ExceptionTechnique("Erreur : le serviceSecurity doit etre fourni");
			}
			_serviceSecurity = serviceSecurity;
			_channelSet = _serviceSecurity.channelConfig.channelSet;
		}
		
		override public function closeSession():void {
			JMCNetLogger.debug("Appel SessionManagerBlazeDSImpl.closeSession");
			
			var token:AsyncToken = _channelSet.logout();
            token.addResponder(new AsyncResponder(onCloseSessionResult,onError));			
			JMCNetLogger.debug("Fin SessionManagerBlazeDSImpl.closeSession OK");
		}
		
		override protected function onCloseSessionResult(evt:ResultEvent, token:Object=null):void {
			JMCNetLogger.debug("Appel SessionManagerBlazeDSImpl.onCloseSessionResult");
			switch (evt.result) {
            	case "success":
                	JMCNetLogger.info("SessionManagerBlazeDSImpl.onCloseSessionResult : logout avec succes");
                	super.onCloseSessionResult(evt);
                	// On le refait une deuxième fois car y a que comme ça que ça marche bien
                	_channelSet.logout();
                	JMCNetLogger.debug("Fin SessionManagerBlazeDSImpl.onCloseSessionResult OK");
                    break;
				default:
					JMCNetLogger.info("SessionManagerBlazeDSImpl.onCloseSessionResult : logout avec erreur : "+evt.result);
            }
		}
		
		override public function retrieveSecurityRoles():void {
			JMCNetLogger.debug("Appel SessionManagerBlazeDSImpl.retrieveSecurityRoles");
			var token:AsyncToken = _serviceSecurity.appeler("getSecurityRoles");
			token.addResponder(new AsyncResponder(onGetRolesResult, onError));
			JMCNetLogger.debug("Fin SessionManagerBlazeDSImpl.retrieveSecurityRoles OK");
		}
		
		override protected function onGetRolesResult(event:ResultEvent, token:Object=null):void {
			JMCNetLogger.debug("Appel SessionManagerBlazeDSImpl.onGetRolesResult event="+event);
			roles = event.result as Array;
			for each (var role:String in roles) {
				JMCNetLogger.debug("Role trouvé : '"+role+"'");
			}
			// BlazeDS 4
			// Maintenant que les roles sont rapatriés, on appelle le callback
			onAuthentication(_loginTemp, true);
			JMCNetLogger.debug("Fin SessionManagerBlazeDSImpl.onGetRolesResult OK nbSecurityRoles="+roles.length+" roles="+roles);
		} 
		
		override public function openSession(login:String, password:String):void {
			JMCNetLogger.debug("Appel SessionManagerBlazeDSImpl.openSession login="+login+" password="+password);
			
			if (!_channelSet.authenticated) {
				var epassword:String = MD5.encrypt(password);
				trace("SessionManagerBlazeDSImpl.openSession : encryptedPassword="+epassword);
				var token:AsyncToken = null;
				try {
					token = _channelSet.login(login, password);
					_loginTemp = login;
                	// Add result and fault handlers.
                	token.addResponder(new AsyncResponder(onOpenSessionResult, onOpenSessionFault));
				} catch (e:Error) {
					// On essaye de se delogguer puis on tente de recommencer.
					JMCNetLogger.error("Erreur à l'ouverture de session : '"+e.message+"'");
					closeSession();
				}
            }
            else {
              	JMCNetLogger.info("SessionManagerBlazeDSImpl : Attention tentative de login alors que déjà authentifié");
            }
			
			JMCNetLogger.debug("Fin SessionManagerBlazeDSImpl.openSession OK");
		}
		
		public function onOpenSessionResult(evt:ResultEvent, token:Object=null):void {
			JMCNetLogger.debug("Appel SessionManagerBlazeDSImpl.onOpenSessionResult evt="+evt+" result="+evt.result as String);
//	KO avec BlazeDS4
//			switch(evt.result) {
//            	case "success":
                	JMCNetLogger.info("SessionManagerBlazeDSImpl : connecté avec succès. login="+_loginTemp);
                	// BlazeDS 4 -> on demande les roles d'abord
					// onAuthentication(_loginTemp, true);
					retrieveSecurityRoles();
//               		break;
//                default:
//					JMCNetLogger.warn("SessionManagerBlazeDSImpl : connecté avec erreur. Erreur="+evt.result.toString());
//					onAuthentication(_loginTemp, false, false, evt.result as String);
//			}
		}
		
		public function onOpenSessionFault(info:FaultEvent, token:Object=null):void	{
			JMCNetLogger.error("SessionManagerBlazeDSImpl.onOpenSessionFault : Erreur lors du login : "+info.fault.faultString+" info.fault.faultCode="+info.fault.faultCode);
			onAuthentication(_loginTemp, false, info.fault.faultCode, info.fault.faultString);
		}
	}
}